package com.wfs.suanfa.nio.demo;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @author: wfs
 * @Date: 2020/4/24 10:23
 * @Description:
 */
public class FileChannelTest {
    public static void main(String[] args) {
        try {
            RandomAccessFile randomAccessFile=new RandomAccessFile("a.txt","rw");
            FileChannel inChannel = randomAccessFile.getChannel();
            ByteBuffer buf=ByteBuffer.allocate(48);
            String newData = "New String to write to file..." + System.currentTimeMillis();
            buf.put(newData.getBytes());
            buf.flip();
            //写入
            //获取文件大小
            long filePointer =inChannel.size();
            //从文件结尾开始写入 不设置的话会将文件内容覆盖 覆盖范围为文件开始位置覆盖到 当前字符结束长度位置
            inChannel.position(filePointer);
            //FileChannel.write()是在while循环中调用的。因为无法保证write()方法一次能向FileChannel写入多少字节， 因此需要重复调用write()方法，直到Buffer中已经没有尚未写入通道的字节。
             //判断buf中是否还有元素
            while (buf.hasRemaining()){
                inChannel.write(buf);
            }
            //force()方法将通道里尚未写入磁盘的数据强制写到磁盘上。出于性能方面的考虑，操作系统会将数据缓存在内存中，所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上
            inChannel.force(true);
            buf.clear();
            //因为在写入时position已经指到文件结尾位置，因此需要将positon设置到初始位置才能读出数据 可以参看CharBufferTest类
            inChannel.position(0);
            //读取
            int read = inChannel.read(buf);
            while (read!=-1){
                soutByts(buf);
                read=inChannel.read(buf);
            }
            // inChannel.truncate(1);方法截取一个文件。截取文件时，文件将中指定长度后面的部分将被删除
            inChannel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static  void soutByts( ByteBuffer buf1){
        buf1.flip();
        while (buf1.hasRemaining()){
            System.out.print((char)buf1.get());
        }
        System.out.println();
        buf1.clear();
    }
}
